package org.example.module.service.impl;

import org.example.module.controller.auth.LoginReq;
import org.example.module.controller.auth.LoginResp;
import org.example.module.entity.SysRole;
import org.example.module.entity.SysUser;
import org.example.module.mapper.SysRoleMapper;
import org.example.module.mapper.SysUserMapper;
import org.example.module.security.JwtTokenUtil;
import org.example.module.security.auth.UserContext;
import org.example.module.service.AuthService;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.security.auth.login.LoginException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author yinjunwu
 */
@Service
public class AuthServiceImpl implements AuthService {

    private final SysUserMapper sysUserMapper;
    private final SysRoleMapper sysRoleMapper;
    private final JwtTokenUtil tokenFactory;

    public AuthServiceImpl(SysUserMapper sysUserMapper, SysRoleMapper sysRoleMapper, JwtTokenUtil tokenFactory) {
        this.sysUserMapper = sysUserMapper;
        this.sysRoleMapper = sysRoleMapper;
        this.tokenFactory = tokenFactory;
    }

    @Override
    public LoginResp login(LoginReq req) throws LoginException {
        SysUser user = new SysUser();
        user.setUserName(req.getUserName());
        user.setPassword(req.getPassword());
        user = sysUserMapper.selectByParam(user);
        if (ObjectUtils.isEmpty(user)) {
            throw new LoginException("用户名或密码错误");
        }
        return packageLoginUser(user);
    }

    /**
     * 打包用户信息
     *
     * @param user user
     * @return AuthResp
     */
    private LoginResp packageLoginUser(SysUser user) {

        SysRole sysRole = sysRoleMapper.selectByRoleId(user.getRoleId());
        String[] jurisdiction = sysRole.getJurisdiction().split("\\|");

        //封装登录用户信息
        UserContext userContext = UserContext.create(user.getUserId(), user.getUserName(),
                mapToGrantedAuthorities(jurisdiction));

        LoginResp resp = new LoginResp();
        resp.setUserName(userContext.getUserName());
        resp.setJurisdiction(sysRole.getJurisdiction());
        resp.setCreateTime(user.getCreateTime());
        resp.setToken(tokenFactory.createAccessToken(userContext));
        resp.setRefreshToken(tokenFactory.createRefreshToken(userContext));
        return resp;
    }

    /**
     * 封装权限信息
     *
     * @param roles roles
     * @return List<GrantedAuthority>
     */
    private static List<GrantedAuthority> mapToGrantedAuthorities(String[] roles) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        return authorities;
    }
}
